home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
mus
/
play
/
tracker_3_19.lzh
/
tracker
/
solaris_audio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-19
|
6KB
|
280 lines
/* ss10_audio.h */
/* $Id: solaris_audio.c,v 1.3 1993/11/19 14:27:06 espie Exp espie $
* $Log: solaris_audio.c,v $
* Revision 1.3 1993/11/19 14:27:06 espie
* Stupid bug.
*
* Revision 3.7 1993/01/06 17:58:39 espie
* *** empty log message ***
*
* Revision 3.6 1992/12/03 15:00:50 espie
* restore stty.
*
* Revision 3.5 1992/11/27 10:29:00 espie
* General cleanup
*
* Revision 3.4 1992/11/24 10:51:19 espie
* Sync pseudo call.
*
* Revision 3.3 1992/11/22 17:20:01 espie
* Added update_frequency call, mostly unchecked
*
* Revision 3.2 1992/11/20 14:53:32 espie
* Added finetune.
*
* Revision 3.1 1992/11/19 20:44:47 espie
* Protracker commands.
*
* Revision 3.0 1992/11/18 16:08:05 espie
* New release.
*
* Revision 1.3 1992/11/17 15:38:00 espie
* discard_buffer() call for snappier interface calls.
* - Unified support for all sparcs.
* - moved down to level 2 io.
*/
#include <stdio.h>
#include "defs.h"
#include "extern.h"
/* changed to sys/audioio from sun/audioio DET */
#include <sys/audioio.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stropts.h>
#include <malloc.h>
/* Ripped out a bunch of #defines DET */
LOCAL char *id = "$Id: solaris_audio.c,v 1.3 1993/11/19 14:27:06 espie Exp espie $";
LOCAL int audio;
LOCAL struct audio_info info;
LOCAL char *buffer;
LOCAL short *sbuffer;
LOCAL int index;
LOCAL int dsize;
LOCAL int stereo;
LOCAL int primary, secondary;
void set_mix(percent)
int percent;
{
percent *= 256;
percent /= 100;
primary = percent;
secondary = 512 - percent;
}
#define abs(x) ((x) < 0 ? -(x) : (x))
LOCAL int available(f)
int f;
{
static int possible[] = { 8000, 9600, 11025, 16000, 18900, 22050, 32000,
37800, 44100, 48000, 0};
int best = 0;
int i;
for (i = 0; possible[i]; i++)
if (abs(possible[i] - f) < abs(best - f))
best = possible[i];
return best;
}
int open_audio(f, s)
int f;
int s;
{
int type;
/* added DET */
audio_info_t stuff;
audio_device_t dev;
/* audio = open("/dev/audio", O_WRONLY|O_NDELAY); */
/* changed to O_WRONLY without NDELAY - overran buffer big time DET */
audio = open("/dev/audio", O_WRONLY);
if (audio == -1)
{
fprintf(stderr, "Error: could not open audio\n");
end_all();
}
if (f == 0)
f = 22050;
/* round frequency to acceptable value */
f = available(f);
/* added DET */
ioctl(audio, AUDIO_GETINFO, &stuff);
ioctl(audio, AUDIO_GETDEV, &dev);
if (strcmp(dev.name,"SUNW,dbri") != 0)
{
stereo = 0;
dsize = 1;
info.play.sample_rate = 8000;
info.play.encoding = AUDIO_ENCODING_ULAW;
info.play.channels = 1;
}
else
{
/* tentative set up */
AUDIO_INITINFO(&info);
info.play.sample_rate = 22050;
info.play.precision = 16;
info.play.encoding = AUDIO_ENCODING_LINEAR;
stereo = 0;
info.play.channels = 1;
dsize = 2;
/* try it */
if (ioctl(audio, AUDIO_SETINFO, &info) != 0)
/* didn't work: fatal problem */
end_all();
}
index = 0;
buffer = (char *)malloc(dsize * info.play.channels * info.play.sample_rate);
sbuffer = (short *) buffer;
if (!buffer)
end_all();
return info.play.sample_rate;
}
void set_synchro(s)
BOOL s;
{
}
int update_frequency()
{
int oldfreq;
oldfreq = info.play.sample_rate;
if (ioctl(audio, AUDIO_GETINFO, &info) == 0)
{
if (oldfreq != info.play.sample_rate)
{
buffer = realloc(buffer,
dsize * info.play.channels * info.play.sample_rate);
sbuffer = (short *)buffer;
return info.play.sample_rate;
}
}
return 0;
}
LOCAL int sign(x)
unsigned char x;
{
return x;
}
/************************************************************************/
/* For routine 'cvt' only */
/************************************************************************/
/* Copyright 1989 by Rich Gopstein and Harris Corporation */
/************************************************************************/
LOCAL unsigned int cvt(ch)
int ch;
{
int mask;
if (ch < 0)
{
ch = -ch;
mask = 0x7f;
}
else
mask = 0xff;
if (ch < 32)
{
ch = 0xF0 | 15 - (ch / 2);
}
else if (ch < 96)
{
ch = 0xE0 | 15 - (ch - 32) / 4;
}
else if (ch < 224)
{
ch = 0xD0 | 15 - (ch - 96) / 8;
}
else if (ch < 480)
{
ch = 0xC0 | 15 - (ch - 224) / 16;
}
else if (ch < 992)
{
ch = 0xB0 | 15 - (ch - 480) / 32;
}
else if (ch < 2016)
{
ch = 0xA0 | 15 - (ch - 992) / 64;
}
else if (ch < 4064)
{
ch = 0x90 | 15 - (ch - 2016) / 128;
}
else if (ch < 8160)
{
ch = 0x80 | 15 - (ch - 4064) / 256;
}
else
{
ch = 0x80;
}
return (mask & ch);
}
void output_samples(left, right)
int left, right;
{
if (stereo)
{
sbuffer[index++] = (left * primary + right * secondary)/256;
sbuffer[index++] = (right * primary + left * secondary)/256;
}
else
switch(info.play.encoding)
{
case AUDIO_ENCODING_LINEAR:
sbuffer[index++] = left + right;
break;
case AUDIO_ENCODING_ULAW:
buffer[index++] = cvt((left + right) /16);
break;
}
}
void flush_buffer()
{
/* added DET */
int bubba;
bubba = write(audio, buffer, dsize * index);
/* added DET */
if (bubba == -1)
perror("write to audio:");
else if (bubba != dsize*index)
printf("Short write of %d bytes\n", bubba);
index = 0;
}
void discard_buffer()
{
ioctl(audio, I_FLUSH, FLUSHW);
}
void close_audio()
{
free(buffer);
close(audio);
}